package com.wss.lsl.lucene.demo.shipin.advanced.query;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.function.FieldScoreQuery;
import org.apache.lucene.util.Version;

public class SearchUtils {

	private static IndexReader reader;

	static {
		try {
			reader = IndexReader.open(FileIndexUtils.getDirectory());
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static IndexSearcher getSearcher() {
		try {
			if (reader == null) {
				reader = IndexReader.open(FileIndexUtils.getDirectory());
			} else {
				IndexReader ir = IndexReader.openIfChanged(reader);
				if (ir != null) {
					reader.close();
					reader = ir;
				}
			}
			return new IndexSearcher(reader);
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void searchByFilter(String queryStr, Filter filter) {

		try {
			IndexSearcher searcher = getSearcher();
			QueryParser parser = new QueryParser(Version.LUCENE_35, "content",
					new StandardAnalyzer(Version.LUCENE_35));
			Query query = parser.parse(queryStr);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			TopDocs tds = null;
			if (filter != null) {
				tds = searcher.search(query, filter, 10);
			} else {
				tds = searcher.search(query, 10);
			}
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(sd.doc + ":(" + sd.score + ")["
						+ doc.get("filename") + "【" + doc.get("path")
						+ "】---->" + doc.get("size") + "-----"
						+ sdf.format(new Date(Long.valueOf(doc.get("date"))))
						+ "]");
			}
			searcher.close();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static void searchBySort(String queryStr, Sort sort) {

		try {
			IndexSearcher searcher = getSearcher();
			QueryParser parser = new QueryParser(Version.LUCENE_35, "content",
					new StandardAnalyzer(Version.LUCENE_35));
			Query query = parser.parse(queryStr);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			TopDocs tds = null;
			if (sort != null) {
				tds = searcher.search(query, 10, sort);
			} else {
				tds = searcher.search(query, 10);
			}
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(sd.doc + ":(" + sd.score + ")["
						+ doc.get("filename") + "【" + doc.get("path")
						+ "】---->" + doc.get("size") + "-----"
						+ sdf.format(new Date(Long.valueOf(doc.get("date"))))
						+ "]");
			}
			searcher.close();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void searchByScoreQuery(String queryStr) {

		try {
			IndexSearcher searcher = getSearcher();

			QueryParser parser = new QueryParser(Version.LUCENE_35, "content",
					new StandardAnalyzer(Version.LUCENE_35));
			Query q = parser.parse(queryStr);
			FieldScoreQuery fsq = new FieldScoreQuery("score",
					FieldScoreQuery.Type.INT);
			Query query = new MyCustomScoreQuery(q, fsq);

			TopDocs tds = null;
			tds = searcher.search(query, 10);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(sd.doc + ":(" + sd.score + ")["
						+ doc.get("filename") + "【" + doc.get("path")
						+ "】---->" + doc.get("size") + "-----"
						+ sdf.format(new Date(Long.valueOf(doc.get("date"))))
						+ "]");
			}
			searcher.close();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void searchByFilenameScoreQuery(String queryStr) {

		try {
			IndexSearcher searcher = getSearcher();

			QueryParser parser = new QueryParser(Version.LUCENE_35, "content",
					new StandardAnalyzer(Version.LUCENE_35));
			Query q = parser.parse(queryStr);
			Query query = new FilenameScoreQuery(q);

			TopDocs tds = null;
			tds = searcher.search(query, 10);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(sd.doc + ":(" + sd.score + ")["
						+ doc.get("filename") + "【" + doc.get("path")
						+ "】---->" + doc.get("size") + "-----"
						+ sdf.format(new Date(Long.valueOf(doc.get("date"))))
						+ "]");
			}
			searcher.close();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void searchByDateScoreQuery(String queryStr) {

		try {
			IndexSearcher searcher = getSearcher();

			QueryParser parser = new QueryParser(Version.LUCENE_35, "content",
					new StandardAnalyzer(Version.LUCENE_35));
			Query q = parser.parse(queryStr);
			Query query = new DateScoreQuery(q);

			TopDocs tds = null;
			tds = searcher.search(query, 10);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(sd.doc + ":(" + sd.score + ")["
						+ doc.get("filename") + "【" + doc.get("path")
						+ "】---->" + doc.get("size") + "-----"
						+ sdf.format(new Date(Long.valueOf(doc.get("date"))))
						+ "]");
			}
			searcher.close();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 自定义parse
	 * 
	 * @param queryStr
	 */
	public static void searchByCustomParse(String queryStr) {

		try {
			IndexSearcher searcher = getSearcher();

			QueryParser queryParser = new CustomParse(Version.LUCENE_35,
					"content", new StandardAnalyzer(Version.LUCENE_35));
			Query query = queryParser.parse(queryStr);

			TopDocs tds = null;
			tds = searcher.search(query, 10);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(sd.doc + ":(" + sd.score + ")["
						+ doc.get("filename") + "【" + doc.get("path")
						+ "】---->" + doc.get("size") + "-----"
						+ sdf.format(new Date(Long.valueOf(doc.get("date"))))
						+ "]");
			}
			searcher.close();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 自定义filter
	 * 
	 * @param queryStr
	 */
	public static void searchByCustomFilter(String queryStr, Filter filter) {

		try {
			IndexSearcher searcher = getSearcher();

			QueryParser queryParser = new QueryParser(Version.LUCENE_35,
					"content", new StandardAnalyzer(Version.LUCENE_35));
			Query query = queryParser.parse(queryStr);

			TopDocs tds = null;
			if (filter != null) {
				tds = searcher.search(query, filter, 100);
			} else {
				tds = searcher.search(query, 100);
			}
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(sd.doc + ":(" + sd.score + ")["
						+ doc.get("filename") + "【" + doc.get("path")
						+ "】---->" + doc.get("size") + "-----"
						+ sdf.format(new Date(Long.valueOf(doc.get("date"))))
						+ "]----" + doc.get("id"));
			}
			searcher.close();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
